/*
 * 代号：凤凰
 * http://www.jphenix.org
 * 2014-06-04
 * V4.0
 */
package com.jphenix.driver.nodehandler.util;

import java.util.ArrayList;
import java.util.List;

import com.jphenix.driver.nodehandler.instancea.NodeHandler;
import com.jphenix.share.tools.StaticHtml;
import com.jphenix.standard.docs.ClassInfo;
import com.jphenix.standard.log.ILog;
import com.jphenix.standard.viewhandler.INodeHandler;
import com.jphenix.standard.viewhandler.IViewHandler;

/**
 * 按照节点模板操作指定节点处理类
 * 
 * 指定的节点中没有标记位置的属性信息
 * 程序通过模板中标记位置的属性信息操作对应的HMTL文件
 * 
 * @author 刘虻
 * 2008-12-10下午06:22:52
 */
@ClassInfo({"2014-06-04 12:47","按照节点模板操作指定节点处理类"})
public class NodeModelHandler {

	
	protected ILog log = null; //日志处理类
	
	/**
	 * 构造函数
	 * 2008-12-10下午06:22:52
	 */
	public NodeModelHandler() {
		super();
	}
	
	/**
	 * 设置日志处理类
	 * 刘虻
	 * 2010-5-18 上午10:58:12
	 * @param log 日志处理类
	 */
	protected void setLog(ILog log) {
		this.log = log;
	}

	
	/**
	 * 通过模板获取指定位置的节点序列
	 * 
	 * 目标对象从模板页面对象中获取信息
	 * <!TARGET URL="" />
	 * 
	 * @author 刘虻
	 * 2008-12-10下午07:05:43
	 * @param mVdh 模板节点对象
	 * @param mCVdh 模板指定位置的循环元素
	 * @param isVirtual 指定循环元素是否为虚拟元素(目标节点中不存在的元素)
	 * @return 指定位置的节点序列
	 * @throws Exception 执行发生异常
	 */
	public List<IViewHandler> getTargetViewDataHandlerList(
			IViewHandler mVdh
			,IViewHandler mCVdh
			,boolean isVirtual) throws Exception  {
		return getTargetViewDataHandlerList(
				mVdh,mCVdh,getObjectVdh(mVdh),isVirtual);
	}
	
	/**
	 * 通过模板中的目标页面路径信息获取目标HMTL对象
	 * 
	 * <!TARGET URL="" />
	 * 
	 * @author 刘虻
	 * 2008-12-11上午11:47:52
	 * @param mVdh 模板对象
	 * @return 目标对象
	 * @throws Exception 执行发生异常
	 */
	protected IViewHandler getObjectVdh(IViewHandler mVdh) throws Exception {
		//获取目标节点对象路径
		String urlInfo = 
			mVdh.getFirstChildNodeByNodeName("!target").getAttribute("url");
		if (urlInfo.length()<1) {
			return null;
		}
		//构建目标节点对象
		IViewHandler oVdh = mVdh.newInstance();
		if (!(oVdh instanceof INodeHandler)) {
			throw new Exception("The Node Model Object Not INodeHandler");
		}
		//设置目标对象
		((INodeHandler)oVdh).setNodeBody(
				StaticHtml.getUrlString(urlInfo,mVdh.getDealEncode(),log));
		return oVdh;
	}
	
	/**
	 * 通过模板获取指定位置的节点序列
	 * @author 刘虻
	 * 2008-12-10下午07:05:43
	 * @param mVdh 模板节点对象
	 * @param mCVdh 模板指定位置的循环元素
	 * @param oVdh 目标节点对象
	 * @param isVirtual 指定循环元素是否为虚拟元素(目标节点中不存在的元素)
	 * @return 指定位置的节点序列
	 * @throws Exception 执行发生异常
	 */
	public List<IViewHandler> getTargetViewDataHandlerList(
			IViewHandler mVdh
			,IViewHandler mCVdh
			,IViewHandler oVdh
			,boolean isVirtual) throws Exception  {
		
		//获取数据表块
		oVdh = 
			getTargetViewDataHandler(mVdh,mCVdh.getParentNode(),oVdh);
		if (oVdh==null) {
			return new ArrayList<IViewHandler>();
		}
		//构建返回值
		ArrayList<IViewHandler> reList = new ArrayList<IViewHandler>();
		if (isVirtual) {
			//节点名序列
			ArrayList<String> nodeNameList = new ArrayList<String>();
			List<IViewHandler> oList = mCVdh.getChildDealNodes(); //获取模板子节点序列
			for (IViewHandler ele:oList) {
				if (ele==null) {
					continue;
				}
				nodeNameList.add(ele.getNodeName());
			}
			if (nodeNameList.size()>0) {
				//获取目标类子节点
				oList = oVdh.getChildDealNodes();
				//构建节点模板
				IViewHandler oMVdh = 
					(IViewHandler)mCVdh.clone();
				oMVdh.removeChildNodes(); //移除虚拟元素中的子节点
				int nodeNamePoint = 0; //节点名指针
				ArrayList<IViewHandler> cNodeList = new ArrayList<IViewHandler>(); //子节点序列
				for(IViewHandler ele:oList) {
					if (ele==null) {
						continue;
					}
					if (ele.getNodeName().equals(nodeNameList.get(nodeNamePoint))) {
						nodeNamePoint++;
						if (nodeNameList.size()<nodeNamePoint) {
							cNodeList.add(ele);
							continue;
						}else {
							cNodeList.add(ele);
							
							nodeNamePoint = 0;
							//构造新的子节点
							IViewHandler oEle = 
								(IViewHandler)oMVdh.clone();
							oEle.addChildNode(cNodeList);
							reList.add(oEle);
							cNodeList = new ArrayList<IViewHandler>();
						}
					}else {
						nodeNamePoint = 0;
					}
				}
			}
		}else {
			//获取节点名
			String nodeName = mCVdh.getNodeName();
			//获取子节点序列
			List<IViewHandler> oList = oVdh.getChildDealNodes();
			for(IViewHandler ele:oList) {
				if (ele==null || !ele.getNodeName().equals(nodeName)) {
					continue;
				}
				reList.add(ele);
			}
		}
		return reList;
	}
	
	/**
	 * 通过指定模板区域获取目标节点对象中的区域(递归)
	 * @author 刘虻
	 * 2008-12-10下午06:25:56
	 * @param mVdh模板节点对象
	 * @param mCVdh 指定模板区域块对象
	 * @param oVdh 目标节点对象
	 * @return 指定的目标区域块
	 * @throws Exception 执行发生异常
	 */
	public IViewHandler getTargetViewDataHandler(
					IViewHandler mVdh,
					IViewHandler mCVdh) throws Exception {
		return getTargetViewDataHandler(mVdh,mCVdh,getObjectVdh(mVdh));
	}
	
	
	/**
	 * 获取新的节点处理类
	 * @author 刘虻
	 * 2008-12-11上午11:54:19
	 * @return 新的节点处理类
	 */
	public INodeHandler getNewNode() {
		//构造模版解析类
		INodeHandler nh = new NodeHandler();
		nh.setWarning(false);
		return nh;
	}
	
	/**
	 * 获取指定节点处理类
	 * @author 刘虻
	 * 2008-12-11上午11:53:36
	 * @param filePath 节点文件绝对路径
	 * @param encoding 编码
	 * @return 指定节点处理类
	 * @throws Exception 执行发生异常
	 */
	public INodeHandler getNode(
			String filePath,String encoding) throws Exception {
		//构造模版解析类
		INodeHandler nh = getNewNode();
		nh.setDealEncode(encoding);
		nh.setFilePath(filePath);
		return nh;
	}
	
	/**
	 * 通过指定模板区域获取目标节点对象中的区域(递归)
	 * @author 刘虻
	 * 2008-12-10下午06:25:56
	 * @param mVdh模板节点对象
	 * @param mCVdh 指定模板区域块对象
	 * @param oVdh 目标节点对象
	 * @return 指定的目标区域块
	 * @throws Exception 执行发生异常
	 */
	public IViewHandler getTargetViewDataHandler(
					IViewHandler mVdh,
					IViewHandler mCVdh
					,IViewHandler oVdh) throws Exception {
		
		//节点名
		String nodeName = mCVdh.getNodeName();
		if (nodeName.length()<1) {
			return null;
		}
		//获取父节点
		IViewHandler pNode = mCVdh.getParentNode();
		if ((mVdh==null && !pNode.isTopNode()) 
				|| (mVdh!=null && !mVdh.equals(pNode))) {
			oVdh = getTargetViewDataHandler(mVdh,pNode,oVdh);
		}
		if (oVdh==null) {
			return null;
		}
		//获取当前子类的同级子类序列
		List<IViewHandler> cList = pNode.getChildDealNodes();
		int point = -1; //当前子类在同级子类中的位置
		for(IViewHandler ele:cList) {
			if (ele==null || !ele.getNodeName().equals(nodeName)) {
				continue;
			}
			point++;
			if (ele.equals(mCVdh)) {
				break;
			}
		}
		if (point<0) {
			return null;
		}
		//目标对象子类元素序列
		List<IViewHandler> oList = oVdh.getChildDealNodes();
		int oPoint = -1; //目标指定子类指针
		for(IViewHandler ele:oList) {
			if (ele==null || !ele.getNodeName().equals(nodeName)) {
				continue;
			}
			oPoint++;
			if (oPoint==point) {
				return ele;
			}
		}
		return null;
	}
	
}
